<?php


namespace App\Http\Controllers\Mp;


use App\Contract\ContractStatus;
use App\Http\Controllers\Controller;
use App\Http\Resources\PaginationCollection;
use App\Http\Service\ContractService;
use App\Http\Service\CountryService;
use App\Http\Service\DeviceService;
use App\Jobs\CheckContract;
use App\Jobs\CheckHouse;
use App\Model\Bill;
use App\Model\BillPay;
use App\Model\Business;
use App\Model\BusinessConf;
use App\Model\Contract;
use App\Model\ContractBreak;
use App\Model\ContractRent;
use App\Model\ContractTenant;
use App\Model\Country;
use App\Model\Device;
use App\Model\House;
use App\Model\Message;
use App\Model\Tenant;
use App\Service\AliyunSms;
use App\Service\Fdd\FddInterface;
use App\User;
use App\Utils\Result;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class ContractController extends Controller
{
    protected FddInterface $fdd;

    public function __construct(FddInterface $fdd)
    {
        $this->fdd = $fdd;
    }

    public function index(Request $request)
    {
        $page = $request->input('page', 1);
        $perPage = 20;

        $query = Contract::query();
        $user = $this->getUser();
        if($user->type == 'admin'){
            $houses = House::query()->whereIn('house_class_id',json_decode($user->class_id))
                ->pluck('id')->toArray();
            $query->whereIn('house_id', $houses);
        }else{
            $query->where('business_id', $this->getBusinessId());
        }
        $status = $request->input('status');
        $house_type = $request->input('house_type');
        $type = $request->input('type');
        $sort_by = $request->input('sort_by', 'id');
        $sort_order = $request->input('sort_order', 'desc');
        $keyword = $request->input('keyword');

        if (in_array($status, [ContractStatus::QIANDINGZHONG, ContractStatus::DAIQIANYUE, ContractStatus::YIQIANYUE, ContractStatus::YITUIFANG])) {
            $query->where('status', $status);
        }
        if ($status == 22) {
            $query->where('status', ContractStatus::YIQIANYUE)->where('expired_at', '<', now()->addDays(7)->toDateString());
        }
        if ($status == 25) {
            $query->where('status', ContractStatus::YIQIANYUE)->where('expired_at', '<', now()->toDateString());
        }
        if ($house_type == 1) {
            $query->whereHas('house', function ($q) {
                $q->where('is_whole', 1);
            });
        }
        if ($house_type == 2) {
            $query->whereHas('house', function ($q) {
                $q->where('is_whole', 0);
            });
        }
        if ($keyword) {
            $query->where(function ($q) use ($keyword) {
                $q->whereHas('house', function ($q) use ($keyword) {
                    $q->where('estate_name', 'like', "%{$keyword}%")->orWhere('name', 'like', "%{$keyword}%");
                })->orWhereHas('contractTenant', function ($q) use ($keyword) {
                    $q->where('name', $keyword);
                });
            });
        }
        if ($type) {
            $query->where('type', $type);
        }
        $query->orderBy($sort_by, $sort_order);
        $data = $query->with('contractTenant', 'contractRent', 'house')
            ->withCount(['bills' => function ($q) {
                $q->where('is_paid', 0)->where('is_close', 0)->where('pay_date', '<', Carbon::now()->toDateString());
            }])
            ->orderBy($sort_by, $sort_order)
            ->whereHas('house')
            ->paginate($perPage, ['*'], 'page', $page);

        return Result::success(new PaginationCollection($data));
    }

    public function detail($id)
    {
        $contract = Contract::with('contractTenant', 'contractRent', 'masterTenant', 'house',
            'business', 'business.user', 'bills', 'bills.house', 'contractBreak')->find($id);
        if (!$contract) {
            return Result::error(404, '记录不存在');
        }
        if ($contract && $contract->house) {
            $contract->house->dianfei = $contract->house->dianfei * 1;
        }
        $contract->has_unpaid_bill = $contract->bills()->where('is_paid', 0)->where('is_close', 0)->count() ? 1 : 0;
        $contract->mp_qrcode = 'https://yimits.oss-cn-beijing.aliyuncs.com/App/73451748583184_.pic.jpg';
        return Result::success($contract);
    }


    /**创建快捷支付
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function createFast(Request $request){
        $deviceId = $request->input('device_id');
        $device = Device::query()->where('id',$deviceId)->first();
        if(!$device){
            return Result::error(402, '设备不存在');
        }
        if(!$device->house_id){
            return Result::error(402, '该设备未绑定房源');
        }
        $business = Business::query()->where('id',$device->business_id)->first();
        if(!$business){
            $need_people = 0;
        }else{
            $user = User::query()->where('id',$business->user_id)->first();
            $need_people = $user->gongan;
        }
//        if($device->house && $user->gongan == 1){
//            $country = Country::query()->get();
//            foreach ($country as $v) {
//                if($v->province == $device->house->province && $v->city == $device->house->city){
//                    if($device->house->district){
//                        if($v->district == $device->house->district){
//                            if($device->house->country && $device->house->country == $v->country){
//                                if($v->name){
//                                    if (strpos($device->house->estate_name, $v->name) !== false) {
//                                        $need_people = $v->type;
//                                        break;
//                                    }
//                                }else{
//                                    $need_people = $v->type;
//                                    break;
//                                }
//                            }else{
//                                if (strpos($device->house->estate_name, $v->name) !== false) {
//                                    $need_people = $v->type;
//                                    break;
//                                }
//                            }
//                        }
//                    }else{
//                        if($device->house->country && $device->house->country == $v->country){
//                            if($v->name){
//                                if (strpos($device->house->estate_name, $v->name) !== false) {
//                                    $need_people = $v->type;
//                                    break;
//                                }
//                            }else{
//                                $need_people = $v->type;
//                                break;
//                            }
//                        }else{
//                            if (strpos($device->house->estate_name, $v->name) !== false) {
//                                $need_people = $v->type;
//                                break;
//                            }
//                        }
//                    }
//                }
//            }
//        }
        $mobile = $request->input('mobile');
        $mobile = (string)$mobile;
        $end = $request->input('end');
        $amount = $request->input('amount',0);
        $deposit = $request->input('deposit',0);
        $is_fail_close = $request->input('is_fail_close',1);
        if(!$end){
            return Result::error(402, '该选择房租到期时间');
        }
        if(!$mobile){
            return Result::error(402, '该填写手机号');
        }
        $businessId = $this->getBusinessId();
        if (Contract::query()->where('house_id', $device->house_id)->where('status', '<=', ContractStatus::YIQIANYUE)->exists()) {
            return Result::error(402, '此房源已存在合同');
        }
        $house = House::query()->where('id',$device->house_id)->first();
        $house->rent = $amount;
        $house->save();
        $device->mobile = $mobile;
        Device::query()->where('mobile', $mobile)->update(['mobile' => NULL]);
        $device->save();
        $user = User::where('mobile', $mobile)->first();
        if (!$user) {
            $user = new User();
            $user->mobile = $mobile;
            $user->type = 'tenant';
            $user->password = Hash::make(substr((string)$mobile, 5));
            $user->save();
            $user->business()->create([
                'name' => '',
            ]);
            $user->tenant()->create([
                'name' => ''
            ]);
        }
        $teanet_num = $request->input('teanet_num',1);
        $type = $request->input('type', 3);
        $contract = new Contract();
        $contract->sn = 'P' . date('YmdHis') . Str::random(4);
        $contract->business_id = $businessId;
        $contract->need_people= $need_people;
        $contract->is_fail_close = $is_fail_close;
        $contract->house_id = $device->house_id;
        $contract->type = $type;
        $contract->mobile = $mobile;
        $contract->teanet_num = $teanet_num;
        $contract->expired_at =  $end;
        $contract->start_at =  date('Y-m-d');
        $contract->status = ContractStatus::FASTQY;
        $contract->save();
        $contractRent = new ContractRent();
        $contractRent->start_at = date('Y-m-d');
        $contractRent->contract_id = $contract->id;
        $contractRent->end_at = $end;
        $contractRent->amount = $amount;
        $contractRent->is_deposit_paid = 1;
        $contractRent->deposit = $deposit;
        $contractRent->save();
        if($need_people != 1){
            $house = $device->house;
            if($house->country_code){
                $business = Business::query()->where('id',$device->business_id)->first();
                $data['name'] = $user->tenant->name?$user->tenant->name:'未实名';
                $data['phone'] = $user->mobile;
                $data['address']  = $house->province.$house->city.$house->district.$house->country.$house->estate_name.$house->name;
                $data['regionCode'] = $house->country_code;
                $data['renttimeStr'] = date('Y-m-d');
                $data['landlordName'] = $business->name?$business->name:'未实名';
                $sUser = $this->getUser();
                $data['landlordPhone'] = $sUser->mobile;
                $service= new CountryService();
                $service->pushTenant($data);
            }
        }
        return Result::success($contract);
    }

    /**快捷出租详情
     * @param Request $request
     * @return void
     */
    public function fastDetail(Request $request){
        $deviceId = $request->input('device_id');
        $businessId = $this->getBusinessId();
        $deviceModel = Device::query()->where('id',$deviceId)->first();
//        if($businessId != $deviceModel->business_id){
//            return Result::error(400, '该设备归属异常');
//        }
        if(!$deviceModel || !$deviceModel->house_id){
            return Result::error(402, '设备或房源不存在');
        }
        $fast = Contract::query()->where('house_id',$deviceModel->house_id)
            ->where('status', ContractStatus::FASTQY)
            ->with('contractRent','contractTenant')
            ->first();
        return Result::success($fast);
    }

    /**快捷出租续租
     * @param Request $request
     * @return void
     */
    public function fastLease(Request $request){
        $contractId = $request->input('id');
        $mobile = $request->input('mobile');
        $end = $request->input('end');
        $teanet_num = $request->input('teanet_num');
        $amount = $request->input('amount',0);
        $deposit = $request->input('deposit',0);
        $is_fail_close = $request->input('is_fail_close',1);
        if(!$end){
            return Result::error(402, '该选择房租到期时间');
        }
        if(!$mobile){
            return Result::error(402, '该填写手机号');
        }
        $contractModel = Contract::query()->where('id',$contractId)->first();
        if(!$contractModel){
            return Result::error(402, '快捷出租信息不存在');
        }
//        $contractModel->mobile = $mobile;
        if($contractModel){
            $device = Device::query()->where('mobile',$contractModel->mobile)->first();
            if($device){
                Device::query()->where('mobile', $mobile)->update(['mobile' => '']);
                $device->mobile=$mobile;
                $device->save();
            }
        }
        $contractModel->expired_at  = $end;
        $contractModel->mobile = $mobile;
        if($teanet_num >=1){
            $contractModel->teanet_num = $teanet_num;
        }
        $contractModel->is_fail_close = $is_fail_close;
        $contractModel->save();
        $contractRent = ContractRent::query()->where('contract_id',$contractId)->first();
        $contractRent->end_at = $end;
        if($amount){
            $contractRent->amount = $amount;
        }
        if($deposit){
            $contractRent->deposit = $deposit;
        }
        $contractRent->save();
        dispatch(new CheckContract($contractId))->delay(3);
        return Result::success($contractModel);
    }

    /**审核
     * @param Request $request
     * @return void
     */
    public function checkTenant(Request $request){
        $contractId = $request->input('contract_id');
        $status = $request->input('status');
        $contract = Contract::query()->where('id',$contractId)->first();
        if(!$contract){
            return Result::error(1001,'快捷信息不存在');
        }
        if($contract->check_status == 1){
            return Result::error(1001,'已确认租客信息');
        }
        $contract->check_status = $status;
        $contract->save();
        return Result::success();
    }


    /**删除承租人信息
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function removeTenant(Request $request){
        $tenantId = $request->input('tenant_id');
        if(!$tenantId){
            return Result::error(402, '缺少参数id');
        }
        ContractTenant::query()->where('id',$tenantId)->delete();
        return Result::success();
    }


    public function create(Request $request)
    {
        $houseId = $request->input('house_id');
        $businessId = $this->getBusinessId();
        $type = $request->input('type', 1);

        if (Contract::query()->where('house_id', $houseId)->where('status', '<=', ContractStatus::YIQIANYUE)->exists()) {
            return Result::error(402, '此房源已存在合同');
        }
        $contract = new Contract();
        $contract->sn = 'P' . date('YmdHis') . Str::random(4);
        $contract->business_id = $businessId;
        $contract->house_id = $houseId;
        $contract->type = $type;

        $contract->save();

        return Result::success($contract);
    }

    public function update(Request $request, $id)
    {
        $contract = Contract::find($id);

        $contract->fill($request->all());
        $contract->save();

        return Result::success($contract);
    }

    // 合同生效
    public function submit(Request $request, $id)
    {
        try {
            DB::beginTransaction();

            $contract = Contract::with('contractRent', 'contractTenant', 'house', 'house.device', 'masterTenant')->find($id);
            if (!$contract->contractRent or !$contract->contractTenant) {
                return Result::error(400, '请完善合同内容');
            }
            if ($contract->contractRent->amount <= 0) {
                return Result::error(400, '房租金额有误');
            }
            $tenantUser = User::query()->where('mobile', $contract->masterTenant->mobile)->first();
            if(!$tenantUser){
                $tenantUser= new User();
                $tenantUser->remember_token = Str::random();
                $tenantUser->password = Hash::make(substr($contract->masterTenant->mobile, -6));
                $tenantUser->mobile = $contract->masterTenant->mobile;
                $tenantUser->type = 'tenant';
                $tenantUser->save();
                $tenantUser = User::query()->where('mobile', $contract->masterTenant->mobile)->with( 'tenant')->first();
                if (!$tenantUser->tenant) {
                    $tenantUser->tenant()->create([
                        'name' => ''
                    ]);
                }
            }
            if ($contract->type == 1 && $contract->status == ContractStatus::QIANDINGZHONG) {
                if (!$contract->contractRent or !$contract->contractTenant) {
                    return Result::error(401, '请完善合同信息');
                }
                $contract->status = ContractStatus::YIQIANYUE;
                $contract->save();

                $contractService = new ContractService();
                $contractService->createBill($contract);
                // 写入租客消息
                Message::create([
                    'user_id'=> $tenantUser->id,
                    'title' => '您有一份新的租房合同已签定',
                    'content' => '房源名称：' . $contract->house->estate_name . $contract->house->name . '，请在我的合同中查看'
                ]);
                // 入驻时清0
                $conf = BusinessConf::query()->where('business_id', $contract->business_id)->first();
                if ($conf->elec_clear_in) {
                    $service = app()->make(DeviceService::class);
                    foreach ($contract->house->device as $d) {
                        if ($d->net_type == 1) {
                            $result = $service->clear($d->mac, 2);
                        }
                    }
                }

            }
            if ($contract->type == 2 && $contract->status == ContractStatus::QIANDINGZHONG) {
                $template_id = $request->input('template_id');
                if (!$contract->contractRent or !$contract->contractTenant or !$template_id) {
                    return Result::error(401, '请完善合同信息');
                }
                $user = $this->getUser();
                //$fdd = $user->fdd()->first();
                // if (!$fdd or $fdd->status != 2) {
                //     return Result::error(401, '您需要先进行实名认证后才能签署电子合同');
                // }

                $contract->template_id = $template_id;
                $contract->save();

                // 写入租客消息
                Message::create([
                    'user_id'=> $tenantUser->id,
                    'title' => '您有一份新的租房合同待签署',
                    'content' => '房源名称：' . $contract->house->estate_name . $contract->house->name . '，请在我的合同中查看并签署'
                ]);
            }
            $device = Device::where('house_id',$contract->house_id)
                ->where('is_disabled',0)
                ->orderBy('id','desc')
                ->first();
            if($device){
                $device->mobile = $contract->mobile;
                $device->save();
            }
            DB::commit();
            return Result::success(['id' => $contract->id]);
        } catch (\Exception $e) {
            Log::error($e);
            DB::rollBack();

            return Result::error(500,$e->getMessage());
        }
    }

    // 延长租期
    public function changeExpireDate(Request $request, $id)
    {
        try {
            DB::beginTransaction();

            $data = $request->only([
                'amount',
                'rent_num',
                'month_num',
                'start_at',
                'pay_type',
                'pay_day',
                'days'
            ]);

            $contract = Contract::with('contractRent', 'contractTenant')->find($id);
            $oldMonthNum = $contract->contractRent->month_num;
            $oldRentNum = $contract->contractRent->rent_num;
            $contract->contractRent->fill($data);
            $contract->contractRent->end_at = Carbon::createFromFormat('Y-m-d', $contract->contractRent->start_at)->addMonths($contract->contractRent->month_num)->subDay()->toDateString();
            $contract->contractRent->save();

            $contract->start_at = Carbon::createFromFormat('Y-m-d', $data['start_at'])->toDateString();
            $contract->expired_at = $contract->contractRent->end_at;
            $contract->c_type = 2;
            $contract->save();

            $month_num = (int)$request->input('month_num');
            if (!$month_num or $month_num < 1) {
                return Result::error(400, '参数错误');
            }

            $lastBill = $contract->bills()->orderByDesc('stage')->first();
            $i = $lastBill->stage + 1;
            if ($month_num > $contract->contractRent->rent_num) {
                $m = 0;
                while ($m < $month_num) {
                    $rent_num = $contract->contractRent->rent_num;
                    if (($month_num - $m) < $rent_num) {
                        $rent_num = $month_num - $m;
                    }
                    $bill = new Bill();
                    $bill->contract_id = $id;
                    $bill->amount = $data['amount'] * $rent_num;
                    $bill->business_id = $contract->business_id;
                    $businessConf = BusinessConf::query()->where('business_id', $contract->business_id)->first();
                    if ($businessConf && $businessConf->fee_payer == 2) {
                        $bill->fee_payer = 2;
                    }else{
                        $bill->fee_payer = 1;
                    }
                    $bill->house_id = $contract->house_id;
                    $bill->mobile = $contract->mobile;
                    $bill->title = "第{$i}期 - 房租";
                    $bill->stage = $i;
                    $bill->type = 1;
                    $start_date = Carbon::createFromFormat('Y-m-d', $data['start_at']);
                    if ($m > 0) {
                        $start_date->addMonths($m);
                    }
                    $end_date = (clone $start_date)->addMonths($rent_num);
                    $bill->start_date = $start_date->toDateString();
                    $bill->end_date = $end_date->toDateString();
                    if ($contract->contractRent->pay_type == 1) {
                        $bill->pay_date = (clone $start_date)->subDays($contract->contractRent->days)->toDateString();
                    } else {
                        $bill->pay_date = (clone $start_date)->firstOfMonth()->addDays($contract->contractRent->pay_day)->toDateString();
                    }
                    $bill->save();
                    $m = $m + $rent_num;
                    $i++;
                }
            } else {
                $bill = new Bill();
                $bill->contract_id = $id;
                $bill->amount = $data['amount'] * $month_num;
                $bill->business_id = $contract->business_id;
                $businessConf = BusinessConf::query()->where('business_id', $contract->business_id)->first();
                if ($businessConf && $businessConf->fee_payer == 2) {
                    $bill->fee_payer = 2;
                }else{
                    $bill->fee_payer = 1;
                }
                $bill->house_id = $contract->house_id;
                $bill->mobile = $contract->mobile;
                $bill->title = "第{$i}期 - 房租";
                $bill->stage = $i;
                $bill->type = 1;
                $start_date = Carbon::createFromFormat('Y-m-d', $data['start_at']);
                $end_date = clone ($start_date)->addMonths($month_num);
                $bill->start_date = $start_date->toDateString();
                $bill->end_date = $end_date->toDateString();
                if ($contract->contractRent->pay_type == 1) {
                    $bill->pay_date = (clone $start_date)->subDays($data['days'])->toDateString();
                } else {
                    $bill->pay_date = (clone $start_date)->firstOfMonth()->addDays($data['pay_day'])->toDateString();
                }
                $bill->save();
            }

            DB::commit();
            return Result::success();
        } catch (\Exception $e) {
            Log::error($e);
            DB::rollBack();

            return Result::error(500);
        }
    }

    /**快捷入住退房
     * @param Request $request
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function breakFast(Request $request,$id){
        $contract = Contract::with('house', 'house.device')->find($id);
        if ($contract->business_id != $this->getBusinessId()) {
            return Result::error(404, '合同不存在');
        }
        if($contract->status == ContractStatus::YITUIFANG){
            return Result::error(404, '已退房 无需重复退房');
        }
        $break_type = $request->input('break_type',1);
        $contract->status = ContractStatus::YITUIFANG;
        $contract->break_type = $break_type;
        $contract->save();
        $break = new ContractBreak();
        $break->contract_id = $contract->id;
        $break->break_type = $break_type;
        $break->break_at = date('Y-m-d');
        $break->save();
        // 退房时电表清0
        return Result::success();
    }
    public function checkRecharge(Request $request){
        $contractId = $request->input('contract_id');
        $contract = Contract::query()->find($contractId);
        if(!$contract){
            return Result::error(404, '快捷信息不存在');
        }
        $contractTenants = ContractTenant::query()->where('contract_id',$contractId)
            ->pluck('mobile')
            ->values()->toArray();
        if(!$contractTenants || $contract->tenant_num > count($contractTenants)){
            return Result::error(404, '尚未完善租客信息');
        }
        $user= $this->getUser();
        if(!in_array($user->mobile,$contractTenants)){
            return Result::error(404, '抱歉！您不是该房间的住户，不能充值！');
        }
        return Result::success();
    }

    // 退房
    public function break(Request $request, $id)
    {
        $contract = Contract::with('house', 'house.device')->find($id);
        if ($contract->business_id != $this->getBusinessId()) {
            return Result::error(404, '合同不存在');
        }

        $balance = $request->input('balance');
        $note = $request->input('note');
        $break_type = $request->input('break_type');
        $break_at = $request->input('break_at');

        $contract->status = ContractStatus::YITUIFANG;
        $contract->break_type = $break_type;
        $contract->save();

        $break = new ContractBreak();
        $break->contract_id = $contract->id;
        $break->balance = $balance;
        $break->break_type = $break_type;
        $break->break_at = $break_at;
        $break->note = $note;
        $break->save();

        Bill::query()->where('contract_id', $contract->id)->where('is_paid', 0)
            ->update([
                'is_close' => 1
            ]);

        // 退房时电表清0
        $conf = BusinessConf::query()->where('business_id', $contract->business_id)->first();
        if ($conf->elec_clear_out) {
            $service = app()->make(DeviceService::class);
            foreach ($contract->house->device as $d) {
                if ($d->net_type == 1) {
                    $result = $service->clear($d->mac, 2);
                }
            }
        }

        return Result::success();
    }

    // 作废
    public function destroy($id)
    {
        $contract = Contract::find($id);
        if (!$contract) {
            return Result::error(404, '合同不存在');
        }
        if ($contract->business_id != $this->getBusinessId()) {
            return Result::error(404, '合同不存在');
        }
        // 删除电子合同签署任务
        if ($contract->status < ContractStatus::YIQIANYUE && $contract->sign_task_id) {
            try {
                $this->fdd->signTaskDelete($contract->sign_task_id);
                $this->fdd->signTaskCancel($contract->sign_task_id);
            } catch (\Exception $e) {
                // todo
            }
        }

        $contract->delete();
        return Result::success();
    }

    /**浙江图片识别
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function ocrCard(Request $request){
        $url = $request->input('url');
        $host = "https://gjbsb.market.alicloudapi.com";
        $path = "/ocrservice/advanced";
        $method = "POST";
        $appcode = "25566481e1c54b85bc164bc988c10294";
        $headers = array();
        array_push($headers, "Authorization:APPCODE " . $appcode);
        //根据API的要求，定义相对应的Content-Type
        array_push($headers, "Content-Type".":"."application/json; charset=UTF-8");
        $querys = "";
        $bodys = "{\"img\":\"\",\"url\":\"{$url}\",\"prob\":false,\"charInfo\":false,\"rotate\":false,\"table\":false}";
        $url = $host . $path;
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HEADER, false);
        if (1 == strpos("$".$host, "https://"))
        {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        curl_setopt($curl, CURLOPT_POSTFIELDS, $bodys);
        $response = curl_exec($curl);
        if (curl_error($curl)) {
            $error_msg = curl_error($curl);
            $error_no = curl_errno($curl);
            curl_close($curl);
            throw new \Exception($error_msg, $error_no);
        }
        curl_close($curl);
        $response = json_decode($response,true);
        if(!array_key_exists('content',$response)){
            return Result::error(404, '解析文本失败');
        }
        $text = $response['content'];

        $startPos = strpos($text, "姓名");
        if ($startPos !== false) {
            // 从'姓名 *'后面开始，找到'公民身份号码'的位置
            $endPos = strpos($text, "公民身份号码");
            if ($endPos !== false) {
                // 截取'姓名 *'和'公民身份号码'之间的内容
                // 注意：我们需要从'姓名 *'后面开始截取，所以要加上'姓名 *'的长度（5个字符加上可能的空格）
                // 但为了简化，我们直接假设'姓名 *'后面紧跟着的就是姓名，没有额外的空格
                $nameLength = $endPos - ($startPos + 6); // 5是'姓名 *'的长度
                $result = substr($text, $startPos + 6, $nameLength);

                // 去除结果字符串两端的空格（尽管在这个特定例子中可能不需要）
                $data['name'] = trim($result);
            } else {
                $data['name']  = '';
            }
        } else {
            $data['name'] = '';
        }
        if(!$data['name']){
            return Result::error(404, '姓名解析失败');
        }
        $startPos = strpos($text, "公民身份号码");
        if ($startPos !== false) {
            // 从'姓名 *'后面开始，找到'公民身份号码'的位置
            $endPos = strpos($text, "性别");
            if ($endPos !== false) {
                $nameLength = $endPos - ($startPos + 18); //
                $result = substr($text, $startPos + 18, $nameLength);

                // 去除结果字符串两端的空格（尽管在这个特定例子中可能不需要）
                $data['num'] = trim($result);
            } else {
                $data['num']  = '';
            }
        } else {
            $data['num'] = '';
        }
        $data['name'] = str_replace(' ','',$data['name']);
        $data['name'] = str_replace('*','',$data['name']);
        $data['name'] = str_replace('Z','',$data['name']);
        $data['num'] = str_replace(' ','',$data['num']);
        $data['num'] = str_replace('*','',$data['num']);
        return Result::success($data);
    }


    /**批量添加承租人
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|void
     */
    public function batchTenant(Request $request){
        $contract_id = $request->input('contract_id');
        $data = $request->input('data');
        if(!is_array($data)){
            $data = json_decode($data,true);
        }
        if (ContractTenant::hasDuplicateIdNo($data, 'id_no')) {
            return Result::error(401, '不可存在相同的身份证号');
        }
        if (ContractTenant::hasDuplicateIdNo($data, 'mobile')) {
            return Result::error(401, '不可存在相同的手机号');
        }
        $teanet_num = Contract::query()->where('id',$contract_id)->value('teanet_num');
        if(count($data) != $teanet_num){
            return Result::error(401, '当前入住人数要求为'.$teanet_num.'人');
        }
        $contractMobile = Contract::query()->where('id',$contract_id)->first();
        foreach($data as $v){
            if($v['is_master'] == 1 && $v['mobile'] != $contractMobile->mobile){
                return Result::error(401, '承租人手机号必须为房东办理的承租人');
            }
        }
        foreach($data as $k => $v){
            if($v['id']) {
                $tenant = ContractTenant::find($v['id']);
                if($tenant->name != $v['name']){
                    $tenant->is_push = 0;
                    $tenant->save();
                }
                if ($tenant->contract_id != $contract_id) {
                    return Result::error(401, '参数错误');
                }
            }else{
                $nowCount = ContractTenant::query()->where('contract_id',$contract_id)->count();
                if($nowCount >= $teanet_num ){
                    return Result::error(401, '入住人数已满');
                }
                $tenant = new ContractTenant();
            }
            if($v['mobile'] == $contractMobile->mobile){
                $v['is_master'] = 1;
            }else{
                $v['is_master'] = 0;
            }
            $tenant->contract_id = $contract_id;
            $tenant->fill($v);
            $tenant->save();
            $result[] = $tenant;
            // 同步账号
            $user = User::query()->where('mobile', $tenant->mobile)->first();
            if (!$user) {
                $user = new User();
                $user->mobile = $tenant->mobile;
                $user->nickname = $tenant->name;
                $user->type = 'tenant';
                $user->password = Hash::make(substr($tenant->mobile, 5));
                $user->save();
                $user->business()->create([
                    'name' => $tenant->name,
                ]);
                $user->tenant()->create([
                    'name' => $tenant->name
                ]);
            } else {
                $user->nickname = $tenant->name;
                $user->type = 'tenant';
                $user->save();
                Tenant::where('user_id', $user->id)->where('name', '')->update([
                    'name' => $tenant->name
                ]);
                Business::where('user_id', $user->id)->where('name', '')->update([
                    'name' => $tenant->name
                ]);
            }
        }
        $contractMobile->check_status = 0;
        $contractMobile->save();
        dispatch(new CheckContract($contract_id))->delay(3);
        return Result::success($result);
    }

    public function updateTenant(Request $request)
    {
        $contract_id = $request->input('contract_id');
        $data = $request->all();
        if ($request->input('sms_code')) {
            if (!AliyunSms::validation($data['mobile'], $data['sms_code'])) {
                return Result::error(401, '短信验证码不正确');
            }
            unset($data['sms_code']);
        }
        if ($request->input('id')) {
            $tenant = ContractTenant::find($request->input('id'));
            if ($tenant->contract_id != $contract_id) {
                return Result::error(401, '参数错误');
            }
        } else {
            $tenant = new ContractTenant();
        }
        $tenant->fill($data);
        $tenant->save();
        if ($tenant->is_master) {
            $contract = Contract::find($contract_id);
            $contract->mobile = $tenant->mobile;
            $contract->save();
        }

        // 同步账号
        $user = User::query()->where('mobile', $tenant->mobile)->first();
        if (!$user) {
            $user = new User();
            $user->mobile = $tenant->mobile;
            $user->nickname = $tenant->name;
            $user->type = 'tenant';
            $user->password = Hash::make(substr($tenant->mobile, 5));
            $user->save();
            $user->business()->create([
                'name' => $tenant->name,
            ]);
            $user->tenant()->create([
                'name' => $tenant->name
            ]);
        } else {
            $user->nickname = $tenant->name;
            $user->type = 'tenant';
            $user->save();
            Tenant::where('user_id', $user->id)->where('name', '')->update([
                'name' => $tenant->name
            ]);
            Business::where('user_id', $user->id)->where('name', '')->update([
                'name' => $tenant->name
            ]);
        }
        dispatch(new CheckContract($contract_id))->delay(3);
        return Result::success($tenant);
    }

    public function updateRent(Request $request)
    {
        $data = $request->all();
        $contract_id = $request->input('contract_id');
        if ($request->input('id')) {
            $rent = ContractRent::find($request->input('id'));
            if ($rent->contract_id != $contract_id) {
                return Result::error(401, '参数错误');
            }
        }
        if ($request->input('id')) {
            $rent = ContractRent::find($request->input('id'));
            if ($rent->contract_id != $contract_id) {
                return Result::error(401, '参数错误');
            }
        } else {
            $rent = new ContractRent();
        }
        if ($request->input('amount') > 5000) {
            return Result::error(401, '单月房租不能超过5000');
        }
        unset($data['rent_num_name']);
        $rent->fill($data);
        $rent->end_at = Carbon::createFromFormat('Y-m-d', $rent->start_at)->addMonths($rent->month_num)->subDay()->toDateString();
        $rent->save();

        $contract = Contract::find($contract_id);
        $contract->start_at = $rent->start_at;
        $contract->expired_at = $rent->end_at;
        $contract->save();

        return Result::success($rent);
    }

    public function sendSmsCode(Request $request)
    {
        $mobile = $request->input('mobile');
        $service = new AliyunSms();
        $service->generate($mobile);

        return Result::success();
    }

    public function previewBill(Request $request)
    {
        $data = $request->only([
            'deposit', // 押金金额
            'amount', // 租金
            'month_num', // 租期 多少月
            'start_at', // 开始时间
            'end_at', // 结束时间
            'pay_type', // 收租方式
            'pay_day', // 固定日
            'days', // 提前多少天
            'rent_num', // 付款方式 几个月
        ]);
        $bills = [];
        if ($data['deposit'] > 0) {
            $bills[] = [
                'title' => '押金',
                'amount' => $data['deposit'],
                'pay_date' => $data['start_at'],
                'start_date' => $data['start_at'],
                'end_date' => $data['end_at']
            ];
        }

        for ($i = 1; $i <= (ceil($data['month_num'] / $data['rent_num'])); $i++) {

            $start_date = Carbon::createFromFormat('Y-m-d', $data['start_at']);
            if ($i > 1) {
                $start_date->addMonths(($i - 1) * $data['rent_num']);
            }
            $end_date = (clone $start_date)->addMonths($data['rent_num']);

            if ($data['pay_type'] == 1) {
                $pay_date = $start_date->subDays($data['days'])->toDateString();
            } else {
                $pay_date = $start_date->firstOfMonth()
                    ->addDays($data['pay_day'])
                    ->toDateString();
            }
            if ($pay_date < now()->toDateString()) {
                $pay_date = now()->toDateString();
            }

            $bills[] = [
                'title' => "第{$i}期 - 房租",
                'amount' => $data['amount'] * $data['rent_num'],
                'pay_date' => $pay_date,
                'start_date' => $start_date->toDateString(),
                'end_date' => $end_date->toDateString()
            ];

        }

        return Result::success($bills);
    }

    public function changeExpiredPreviewBill(Request $request, $id)
    {
        $data = $request->only([
            'amount',
            'rent_num',
            'month_num',
            'start_at',
            'pay_type',
            'pay_day',
            'days'
        ]);
        $contract = Contract::with('contractRent', 'contractTenant')->find($id);
        $oldMonthNum = $contract->contractRent->month_num;
        $oldRentNum = $contract->contractRent->rent_num;

        $month_num = (int)$request->input('month_num');
        if (!$month_num or $month_num < 1) {
            return Result::error(400, '参数错误');
        }

        $bills = [];

        $lastBill = $contract->bills()->orderByDesc('stage')->first();
        $i = $lastBill->stage + 1;
        if ($month_num > $data['rent_num']) {
            $m = 0;
            while ($m < $month_num) {
                $rent_num = $data['rent_num'];
                if (($month_num - $m) < $rent_num) {
                    $rent_num = $month_num - $m;
                }
                $start_date = Carbon::createFromFormat('Y-m-d', $data['start_at']);
                if ($m > 0) {
                    $start_date->addMonths($m);
                }
                $end_date = (clone $start_date)->addMonths($rent_num);

                if ($contract->contractRent->pay_type == 1) {
                    $pay_date = (clone $start_date)->subDays($data['days'])->toDateString();
                } else {
                    $pay_date = (clone $start_date)->firstOfMonth()->addDays($data['pay_day'])->toDateString();
                }
                $bills[] = [
                    'title' => "第{$i}期 - 房租",
                    'amount' => $data['amount'] * $rent_num,
                    'pay_date' => $pay_date,
                    'start_date' => $start_date->toDateString(),
                    'end_date' => $end_date->toDateString()
                ];
                $m = $m + $rent_num;
                $i++;
            }
        } else {
            $start_date = Carbon::createFromFormat('Y-m-d', $data['start_at']);
            $end_date = clone ($start_date)->addMonths($month_num);

            if ($contract->contractRent->pay_type == 1) {
                $pay_date = (clone $start_date)->subDays($data['days'])->toDateString();
            } else {
                $pay_date = (clone $start_date)->firstOfMonth()->addDays($data['pay_day'])->toDateString();
            }
            $bills[] = [
                'title' => "第{$i}期 - 房租",
                'amount' => $data['amount'] * $month_num,
                'pay_date' => $pay_date,
                'start_date' => $start_date->toDateString(),
                'end_date' => $end_date->toDateString()
            ];
        }

        return Result::success($bills);
    }

}
